﻿using Ldt.InformationUnit.Common;
using LdtJudge.DataEngine.CallInterface.ConfiCenter;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.Common.DataSave;
using LdtJudge.DataEngine.Common.XmlUtility;
using LdtJudge.DataEngine.Data.DataParseStorage;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.XMLConfigModel.DataStores;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Ldt.DataEngin.Assemble
{
    /// <summary>
    /// 数据源管理
    /// </summary>
    public class DataSourceManage
    {
        #region 基础信息
        /// <summary>
        /// 上下文
        /// </summary>
        public DataContext dataContext;
        /// <summary>
        /// 数据保存基础路径
        /// </summary>
        private string FilestoreUrl = ConfigRetrieval.GetConfigRetrieval.GetAppSettingString("ldt.elementcenterfilestore");
        #endregion

        /// <summary>
        /// 数据源删除
        /// </summary>
        public void DataSourceRemove()
        {
            XmlUtilCommon xmlUtilCommon = new XmlUtilCommon() { dataContext = dataContext };
            //获取案件要素优选结果数据
            List<DataModel> optAllDatas = GetOptimzeResultData("3");
            if (optAllDatas != null && optAllDatas.Any())
            {
                XmlDocument optResultDoc = xmlUtilCommon.DataModelByXml(optAllDatas, "");
                dataContext.InteractiveShow.LogShow($"上次优选结果：{optResultDoc.OuterXml}");
                dataContext.DataLayerOpt.SourdatModleList = new List<DataModel>();
                //案由数据字典，Key--案由信息节点的父级Id  value--案由信息和案由信息的子节点DataModel
                Dictionary<string, List<DataModel>> causeDic = new Dictionary<string, List<DataModel>>();
                if (optAllDatas.Exists(x => x.XmlPath.Contains("案由信息")))
                {
                    //案由信息节点数据
                    List<DataModel> causeNodes = optAllDatas.Where(x => x.XmlPath.EndsWith("案由信息")).ToList();
                    foreach (var causeNode in causeNodes)
                    {
                        string causeKey = causeNode.ParentId;
                        List<DataModel> causeNodeSubs = xmlUtilCommon.SubordinateDataModelList(optAllDatas, causeNode);
                        List<string> causeDataIds = new List<string>();
                        if (causeNodeSubs != null && causeNodeSubs.Any())
                            causeDataIds = causeNodeSubs.Select(x => x.ID).ToList();
                        if (!causeDic.ContainsKey(causeKey) && causeDataIds != null && causeDataIds.Any())
                        {
                            causeDic.Add(causeKey, causeNodeSubs);
                            //从上次优选结果中去除案由数据
                            optAllDatas.RemoveAll(x => causeDataIds.Contains(x.ID));
                        }
                    }
                }
                List<DataModel> caseElementDatas = new List<DataModel>();
                if(optAllDatas!=null && optAllDatas.Any())
                    caseElementDatas=optAllDatas.Select(item => item.Clone()).ToList();
                if (caseElementDatas!=null && caseElementDatas.Any())
                {
                    //删除案件要素节点和节点属性的数据源
                    CaseElementSourceRemove(caseElementDatas);
                    dataContext.DataLayerOpt.SourdatModleList.AddRange(caseElementDatas);
                }
                if(causeDic.Keys.Any())
                {
                    foreach (var causeKeyItem in causeDic.Keys)
                    {
                        if(caseElementDatas.Any(x=>x.ID== causeKeyItem))
                        {
                            dataContext.DataLayerOpt.SourdatModleList.AddRange(causeDic[causeKeyItem]);
                        }
                    }
                }
                if(dataContext.DataLayerOpt.SourdatModleList.Any())
                {
                    try
                    {
                        dataContext.DataLayerOpt.SourdatModleList = dataContext.DataLayerOpt.SourdatModleList.GroupBy(p => p.ID).Select(g => g.First()).ToList();
                        dataContext.DataLayerOpt.OptimizationXml = xmlUtilCommon.DataModelByXml(dataContext.DataLayerOpt.SourdatModleList, "");
                        dataContext.InteractiveShow.LogShow($"删除【{dataContext.DataLayerOpt.SourceCode}】后结果：{dataContext.DataLayerOpt.OptimizationXml.OuterXml}");
                        //保存优选结果
                        dataContext.InteractiveShow.LogShow("***************************" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "--->开始执行优选数据保存*****************************");
                        DataResultSave dataResultSave = new DataResultSave(dataContext);
                        dataResultSave.OptimizationSave();
                        dataContext.InteractiveShow.LogShow("***************************" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "--->优选数据保存执行完成*****************************");
                    }
                    catch (Exception ex)
                    {
                        dataContext.InteractiveShow.LogShow("数据优选保存错误：" + ex.ToString(), LogMessageType.Error);
                    }
                }
            }
        }

        /// <summary>
        /// 删除案件要素节点和节点属性的数据源
        /// </summary>
        /// <param name="caseElementDatas">案件要素节点数据</param>
        public void CaseElementSourceRemove(List<DataModel> caseElementDatas)
        {
            //获取案件要素优选配置
            OptimizeConfig optimizeConfig = null;
            string filePath = $"config/moduleconfig/commonconfig/optimizeconfig/caseoptimize/{dataContext.DataLayerOpt.CaseType.ToLower()}.xml";
            var optimzeContent = GetConfigContent(filePath);
            if(!string.IsNullOrWhiteSpace(optimzeContent))
                optimizeConfig= XmlUtility.DeserializeToObject<OptimizeConfig>(optimzeContent);
            List<string> delIds = new List<string>();
            //数据源字典，用来记录数据源配置Id的下标和数据源编号
            Dictionary<int, string> sourceIndexDic = new Dictionary<int, string>();
            foreach (var dataItem in caseElementDatas)
            {
                sourceIndexDic.Clear();
                if(dataItem.sourceData.sourceList.Exists(x => x.SourceCode.ToLower() == dataContext.DataLayerOpt.SourceCode.ToLower()))
                {
                    dataContext.InteractiveShow.LogShow($"案件要素节点【{dataItem.XmlPath}】删除数据源【{dataContext.DataLayerOpt.SourceCode}】");
                    #region 删除节点数据源
                    //节点删除数据源后，如果没有数据源了就删除节点，如果数据源只有一条，则选中该数据源，如果还有多条数据源，通过优先级选中数据源
                    dataItem.sourceData.sourceList.RemoveAll(x => x.SourceCode.ToLower() == dataContext.DataLayerOpt.SourceCode.ToLower());
                    string checkSourceCode = string.Empty;
                    bool isDelNode = false;
                    if (dataItem.sourceData.sourceList==null || dataItem.sourceData.sourceList.Count == 0)
                    {
                        delIds.Add(dataItem.ID);
                        isDelNode = true;
                        dataContext.InteractiveShow.LogShow($"删除ID为【{dataItem.ID}】XPath路径为【{dataItem.XmlPath}】的节点");
                    }
                    else
                    {
                        if (dataItem.sourceData.sourceList.Count == 1)
                        {
                            dataItem.sourceData.sourceList.FirstOrDefault().IsCheck = "1";
                        }
                        else
                        {
                            //节点数据源中没有IsCheck==1的通过选中配置中优先级高的数据源
                            if (!dataItem.sourceData.sourceList.Any(x => x.IsCheck == "1"))
                            {
                                var sourceDatadefine = optimizeConfig.Sourcedatadefine.FirstOrDefault();
                                Xmllable xmllableCofig = optimizeConfig.XmllableList.FirstOrDefault(a => a.Xmlpath == dataItem.XmlPath);
                                foreach (var sourceItem in dataItem.sourceData.sourceList)
                                {
                                    string currentCode = sourceItem.SourceCode.ToLower();
                                    //数据源配置Id
                                    string sourceNum = sourceDatadefine.SourcedataList.FirstOrDefault(x => x.Code.ToLower() == currentCode)?.id.ToString();
                                    int sourceIndex = 0;
                                    if (!string.IsNullOrWhiteSpace(sourceNum))
                                    {
                                        //数据源配置Id在优先级中的下标
                                        sourceIndex = ListByCount(xmllableCofig.Priority.Split('>').ToList(), sourceNum);
                                        if (sourceIndex>0 && !sourceIndexDic.ContainsKey(sourceIndex))
                                            sourceIndexDic.Add(sourceIndex, sourceItem.SourceCode);
                                    }
                                }
                                if (sourceIndexDic.Keys.Any())
                                {
                                    int checkIndex = sourceIndexDic.Keys.Min();
                                    checkSourceCode = sourceIndexDic[checkIndex];
                                }
                                if (!string.IsNullOrWhiteSpace(checkSourceCode))
                                    dataItem.sourceData.sourceList.FirstOrDefault(x => x.SourceCode == checkSourceCode).IsCheck = "1";
                                else
                                    dataItem.sourceData.sourceList.FirstOrDefault().IsCheck = "1";
                            }
                        }
                    }
                    #endregion
                    #region 删除节点属性数据源
                    if(!isDelNode && dataItem.AttributesList!=null && dataItem.AttributesList.Any())
                    {
                        List<AttributeInfo> delAttrs = new List<AttributeInfo>();
                        foreach (var attrItem in dataItem.AttributesList)
                        {
                            dataContext.InteractiveShow.LogShow($"案件要素节点属性【{dataItem.XmlPath}/@{attrItem.Name}】删除数据源【{dataContext.DataLayerOpt.SourceCode}】");
                            attrItem.sourceList.RemoveAll(x => x.SourceCode.ToLower() == dataContext.DataLayerOpt.SourceCode.ToLower());
                            if (attrItem.sourceList.Count == 0)
                            {
                                delAttrs.Add(attrItem);
                                
                            }
                            else
                            {
                                if (!attrItem.sourceList.Any(x => x.IsCheck == "1"))
                                {
                                    if (attrItem.sourceList.Count == 1 || string.IsNullOrWhiteSpace(checkSourceCode))
                                    {
                                        attrItem.sourceList.FirstOrDefault().IsCheck = "1";
                                    }
                                    else
                                    {
                                        attrItem.sourceList.FirstOrDefault(x => x.SourceCode == checkSourceCode).IsCheck = "1";
                                    }
                                }
                                
                            }
                        }
                        if(delAttrs!=null && delAttrs.Any())
                        {
                            foreach (var delAttrItem in delAttrs)
                            {
                                dataContext.InteractiveShow.LogShow($"删除ID为【{dataItem.ID}】XPath路径为【{dataItem.XmlPath}】节点的属性{delAttrItem.Name}");
                                dataItem.AttributesList.Remove(delAttrItem);
                            }
                        }
                    }
                    #endregion
                }
            }
            if(delIds.Any())
            {
                caseElementDatas.RemoveAll(x => delIds.Contains(x.ID));
            }
        }

        /// <summary>
        /// 获取优选结果数据
        /// </summary>
        /// <param name="dataType">数据类型 1.优选结果全数据 2.案由要素 3.案件要素 4.优选结果xml</param>
        /// <returns></returns>
        private List<DataModel> GetOptimzeResultData(string dataType)
        {
            List<DataModel> result = new List<DataModel>();
            DAL_An_anjiancunchu anjiancunchudal = new DAL_An_anjiancunchu();
            var anjiancunchuList = anjiancunchudal.GetList(dataContext.DataLayerOpt.CaseId, dataType);
            if (anjiancunchuList.Count > 0)
            {
                
                DataSoursModel dataSoursModel = GetDataSoursModel(ReadDataXML(anjiancunchuList[0].Wenjianid));
                result = dataSoursModel.dataModelList;
            }
            return result;
        }

        /// <summary>
        /// 转换出数据源实体
        /// </summary>
        /// <param name="xmlDocument">XML数据</param>
        /// <returns></returns>
        private DataSoursModel GetDataSoursModel(XmlDocument xmlDocument)
        {
            DataSoursModel soursModel = new DataSoursModel();
            if (!string.IsNullOrEmpty(xmlDocument.OuterXml))
            {
                soursModel = XmlUtility.DeserializeToObject<DataSoursModel>(xmlDocument.OuterXml.Replace("&#x", ""));
                foreach (DataModel dataModel in soursModel.dataModelList)
                {
                    dataModel.XmlPath = dataModel.XmlPath.Replace("\\", "/");
                }
            }
            return soursModel;
        }

        /// <summary>
        /// 获取XML数据
        /// </summary>
        /// <param name="id">xml文件Id</param>
        /// <returns></returns>
        private XmlDocument ReadDataXML(string id)
        {
            XmlDocument xmlDocument = new XmlDocument();
            dynamic message = HttpHelp.HttpGet(FilestoreUrl + "/api/XmlDataManage/GetXmlContent/" + id, "");
            string messagex = message;
            xmlDocument.LoadXml(messagex.Replace("&#x13;", "").Replace("&#x14;", "").Replace("&#x15;", "").Replace("&#xD;", ""));
            return xmlDocument;
        }

        /// <summary>
        /// 获取配置配置文件内容
        /// </summary>
        /// <param name="filePath">配置文件路径</param>
        /// <returns></returns>
        private string GetConfigContent(string filePath)
        {
            string configContent = string.Empty;
            Dictionary<string, string> dicElement = new Dictionary<string, string>();
            dicElement.Add("fileFullName", filePath);
            string elementMessage = WebUtil.DoGet(ConfigRetrieval.GetConfigRetrieval.GetAppSettingString("systemapi") + "/api/WordParse/GetConfigFileContent", dicElement, "utf-8");
            dynamic elementcofig = JsonConvert.DeserializeObject<dynamic>(elementMessage);
            if (elementcofig.result.code.ToString() == "1")
                configContent = elementcofig.body;
            return configContent;
        }

        /// <summary>
        /// 计算当前元素在List中的第几位
        /// </summary>
        /// <param name="list">集合</param>
        /// <param name="name">值</param>
        /// <returns></returns>
        private int ListByCount(List<string> list, string name)
        {
            for (int i = 0; i < list.Count; i++)
            {
                if (name?.ToLower() == list[i])
                {
                    return i + 1;
                }
            }
            return 0;
        }
    }
}
